<template>
  <div class="lucky-wrp">
    <div class="lucky-wheel">
      <div class="lucky-title d-flex flex-column justify-content-end align-items-center">
        <div class="bg"></div>
        <div class="join-num flex-item">已有{{totalInvoke}}人参与</div>
      </div>
      <div class="lucky-chance d-flex justify-content-center">
        <span class="flex-item text">您今天还有<b class="num">{{lotteryTicket}}</b>次机会</span>
      </div>
      <div class="wheel-main">
        <canvas ref="wheelRef" class="wheel"></canvas>
        <img src="../../assets/images/lucky/start.png" class="img-spin" @click="rotateHandle()" />
      </div>
    </div>
    <div class="main">
      <div class="statement">
        <p class="text">*奖品与活动由第三方提供，与深圳市甘怡信息技术有限公司无关</p>
      </div>
    </div>
    <div class="toast" v-show="toastControl">
      <div class="toast-container">
        <div class="price">
          <div class="title">恭喜您获得</div>
          <div class="name">{{prize.name}}</div>
        </div>
        <a :href="prize.link" class="btn btn-go">立即领取</a>
      </div>
      <div class="toast-btn">
        <i class="icon-close" @click="closeToast()"></i>
      </div>
    </div>
    <div class="toast-mask" v-show="toastControl"></div>
  </div>
</template>

<script type="text/ecmascript-6">
import {luckyDraw, luckyInfo} from '@/service/index'
import {Storage} from '@/config/mUtils'

export default {
  data() {
    return {
      lotteryTicketKey: 'lottery_ticket',
      totalInvoke: 0,
      lotteryTicket: 0, // 抽奖次数
      toastControl: false, // 抽奖结果弹出框控制器
      hasPrize: false, // 是否中奖
      clickFlag: true, // 是否可以旋转抽奖
      index: 0,
      prizes: [],
      prize: {},
      ctx: null,
      wheelWidth: 0,
      wheelHeight: 0,
      wheelRadius: 0,
      inRadius: 0,
      textRadius: 0,
      centerX: 0,
      centerY: 0,
      startRadian: 2 * Math.PI / 360 * (-90),
      pirzeRadian: 0
    }
  },
  mounted() {
    this.initWheel()
    let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
    window.addEventListener(resizeEvt, this.onResize, false)
  },
  created() {
    let date = new Date()
    let day = (date.getFullYear() + '' + (date.getMonth() + 1) + '' + date.getDate())
    this.lotteryTicketKey = this.lotteryTicketKey + day

    let lotteryTicket = Storage.getStore(this.lotteryTicketKey)
    if (!lotteryTicket && parseInt(lotteryTicket) !== 0) {
      this.setLotteryTicket(8)
      this.lotteryTicket = 8
    } else {
      this.lotteryTicket = parseInt(lotteryTicket)
    }
    this.initPrizes()
  },
  computed: {
    toastTitle() {
      return this.hasPrize
        ? '恭喜您，获得' + this.prize.name
        : '未中奖'
    },
    toastPictrue() {
      return this.hasPrize
        ? require('../../assets/images/lucky/congratulation.png')
        : require('../../assets/images/lucky/sorry.png')
    }
  },
  methods: {
    onResize() {
      this.initWheel()
      this.drawRouletteWheel()
    },
    initWheel() {
      let fontSize = document.querySelector('html').style.fontSize.replace('px', '')
      let wh = 12.2 * fontSize
      this.ctx = this.$refs.wheelRef.getContext('2d')
      this.$refs.wheelRef.width = this.$refs.wheelRef.height = wh
      this.wheelWidth = wh - 20
      this.wheelHeight = wh - 20
      this.wheelRadius = this.wheelWidth / 2
      this.centerX = wh / 2
      this.centerY = wh / 2
      this.textRadius = this.wheelRadius - 50
      this.ctx.translate(this.centerX, this.centerY)
    },
    drawRouletteWheel(angelTo) {
      angelTo = angelTo || 0

      let context = this.ctx

      // ----- ① 清空页面元素，用于逐帧动画
      context.clearRect(-this.wheelWidth, -this.wheelHeight, this.wheelWidth, this.wheelHeight)

      for (let i = 0; i < this.prizes.length; i++) {
        // 每一个奖项所占的起始弧度
        let _startRadian = this.startRadian + this.pirzeRadian * i

        // 每一个奖项的终止弧度
        let _endRadian = _startRadian + this.pirzeRadian

        // ----- ② 使用非零环绕原则，绘制圆盘
        context.save()
        context.rotate(angelTo * Math.PI / 180)
        context.translate(-this.centerX, -this.centerY)
        context.beginPath()
        context.lineWidth = 16
        context.strokeStyle = '#D0232A'
        context.arc(this.centerX, this.centerY, this.wheelRadius, 0, 2 * Math.PI)
        context.stroke()

        // 装饰点
        let dotColor = ['#f9ebbd', '#feb906']
        let startRadian = this.startRadian
        for (let i = 0; i < 12; i++) {
          context.translate(this.centerX, this.centerY)
          // 装饰点 圆心 坐标计算
          context.beginPath()
          let radius = this.wheelRadius
          let xr = radius * Math.cos(startRadian)
          let yr = radius * Math.sin(startRadian)

          context.fillStyle = dotColor[i % dotColor.length]
          context.arc(xr, yr, 6, 0, 2 * Math.PI)
          context.fill()

          startRadian += (2 * Math.PI / 360) * (360 / 12)
          context.translate(-this.centerX, -this.centerY)
        }

        if (i % 2 === 0) {
          context.fillStyle = '#FFB138'
        } else {
          context.fillStyle = '#FDD67C'
        }

        context.beginPath()
        context.arc(this.centerX, this.centerY, this.wheelRadius - 8, _startRadian, _endRadian, false)
        context.arc(this.centerX, this.centerY, this.inRadius, _endRadian, _startRadian, true)
        context.fill()
        context.restore()

        // ----- ③ 绘制文字
        context.save()
        context.rotate(angelTo * Math.PI / 180)
        context.translate(-this.centerX, -this.centerY)
        context.font = 'bold 14px Helvetica, Arial'
        context.fillStyle = '#D0232A'
        context.translate(
          this.centerX + Math.cos(_startRadian + this.pirzeRadian / 2) * this.textRadius,
          this.centerY + Math.sin(_startRadian + this.pirzeRadian / 2) * this.textRadius
        )

        context.rotate(_startRadian + this.pirzeRadian / 2)
        context.fillText(this.prizes[i].name, -context.measureText(this.prizes[i].name).width / 2, 0)
        context.restore()
      }
    },
    rotateWheel() {
      this.clickFlag = false
      let angel = this.getPrizeAngle()
      angel = 360 - angel
      angel += 720
      // 基值（减速）
      var baseStep = 30
      // 起始滚动速度
      var baseSpeed = 0.3
      // 步长
      var count = 1
      var timer = setInterval(() => {
        this.drawRouletteWheel(count)
        if (count === angel) {
          setTimeout(() => {
            this.gameOver()
          }, 500)
          this.clickFlag = true
          clearInterval(timer)
        }
        count = count + baseStep * (((angel - count) / angel) > baseSpeed ? baseSpeed : ((angel - count) / angel))
        if (angel - count < 0.5) {
          count = angel
        }
      }, 15)
    },
    getPrize() {
      let startAngle = this.startRadian * 180 / Math.PI
      let awardAngle = this.pirzeRadian * 180 / Math.PI
      let pointerAngle = 90
      let overAngle = (startAngle + pointerAngle) % 360
      let restAngle = 360 - overAngle
      let index = Math.floor(restAngle / awardAngle)
      return index
    },
    getPrizeAngle() {
      let count = 0
      for (const key in this.prizes) {
        if (this.prizes.hasOwnProperty(key)) {
          if (this.prize.id === this.prizes[key].id) {
            break
          }
          count++
        }
      }

      return (count * 360 / this.prizes.length + 360 / this.prizes.length / 2)
    },
    // 此方法为处理奖品数据
    initPrizes() {
      if (this.prizes.length <= 0) {
        luckyInfo()
        .then(resp => {
          this.prizes = resp.data.prizes
          this.totalInvoke = resp.data.totalInvoke
          this.pirzeRadian = (Math.PI * 2) / this.prizes.length
          this.drawRouletteWheel()
        })
        .catch(error => {
          console.log(error)
        })
      }
    },
    rotateHandle() {
      if (this.clickFlag && this.lotteryTicket > 0) {
        luckyDraw()
        .then(resp => {
          this.setLotteryTicket(--this.lotteryTicket)
          this.index = resp.data.id // 指定每次旋转到的奖品下标
          this.setPrize()
          this.rotateWheel()
        })
        .catch(error => {
          console.log(error)
        })
      }
    },
    gameOver() {
      this.toastControl = true
      this.hasPrize = this.prize.is_prize
    },
    // 关闭弹窗
    closeToast() {
      this.toastControl = false
    },
    setPrize() {
      for (let i = 0, len = this.prizes.length; i < len; i++) {
        if (parseInt(this.prizes[i].id) === parseInt(this.index)) {
          this.prize = this.prizes[i]
          break
        }
      }
    },
    setLotteryTicket(n) {
      Storage.setStore(this.lotteryTicketKey, n)
    }
  }
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
  @import "../../common/stylus/mixin.styl"
  @import "../../common/stylus/variable.styl"

  .lucky-wrp
    position: relative
    width: 100%
    height: 100%
    background: rgb(254, 69, 69)
    bg-image('../../assets/images/lucky/bg')
    background-repeat: no-repeat
    background-size: 100% 100%
    .lucky-wheel
      width: 100%
      padding-top: 0.4454rem
      .lucky-title
        position: relative
        width: 100%
        height: 6.4961rem
        .bg
          width: 100%
          height: 90%
          bg-image('../../assets/images/lucky/title')
          background-position: center top
          background-repeat: no-repeat
          background-size: 85%
        .join-num
          position: absolute
          background: rgb(159, 17, 29)
          color: rgb(255, 248, 108)
          font-size: 14px
          padding: 0.3rem 0.4rem 0.3rem 0.4rem
      .lucky-chance
        padding: 8px 0px 4px 0px
        margin-top: 0.4rem
        margin-bottom: 8px
        .text
          font-size: 14px
          color: #fff
          .num
            padding: 0 4px
            color: rgb(255, 248, 108)
            font-size: 18px
      .wheel-main
        position: relative
        display: flex
        align-items: center
        justify-content: center
        .img-spin
          position: absolute
          width: 76px
          height: 81px
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%)
    .main
      position: relative
      width: 100%
      padding-bottom: 0.9130rem
      .statement
        margin-top: 5.4rem
        padding: 0 0.64rem
        line-height: 22px
        .text
          color: $color-light-grey-s
          font-size: 12px
    .toast-mask
      position: fixed
      top: 0
      left: 0
      background: rgba(0, 0, 0, 0.6)
      z-index: 10
      width: 100%
      height: 100%
    .toast
      position: fixed
      top: 50%
      left: 50%
      z-index: 20
      transform: translate(-50%, -50%)
      width: 12.3527rem
      height: 16.8527rem
      border-radius: 0.1691rem
      padding: 0.1691rem
      .toast-container
        position: relative
        width: 100%
        height: 100%
        bg-image('../../assets/images/lucky/has-price')
        background-position: center top
        background-repeat: no-repeat
        background-size: 100% 100%
        .price
          position: absolute
          top: 7.8rem
          left: 50%
          transform: translate(-50%, 0)
          .name
            line-height: 24px
            font-size: 20px
            font-weight: 600
            color: #fff
            text-align: center
          .title
            padding-bottom: 0.78rem
            font-size: 20px
            color: #fff
            text-align: center
        .btn-go
          position: absolute
          padding: 6px 1.8rem
          top: 12.8rem
          left: 50%
          transform: translate(-50%, 0)
      .toast-btn
        margin-top: 0.6rem
        text-align: center
        .icon-close
          color: #fff
          font-size: 22px
</style>